﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.U2D.SpriteDataAccessExtensions
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Runtime.CompilerServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.Bindings;
using UnityEngine.Rendering;

#nullable disable
namespace UnityEngine.U2D
{
  /// <summary>
  ///   <para>A list of methods designed for reading and writing to the rich internal data of a Sprite.</para>
  /// </summary>
  [NativeHeader("Runtime/2D/Common/SpriteDataAccess.h")]
  [NativeHeader("Runtime/Graphics/SpriteFrame.h")]
  public static class SpriteDataAccessExtensions
  {
    private static void CheckAttributeTypeMatchesAndThrow<T>(VertexAttribute channel)
    {
      bool flag;
      switch (channel)
      {
        case VertexAttribute.Position:
        case VertexAttribute.Normal:
          flag = typeof (T) == typeof (Vector3);
          break;
        case VertexAttribute.Tangent:
          flag = typeof (T) == typeof (Vector4);
          break;
        case VertexAttribute.Color:
          flag = typeof (T) == typeof (Color32);
          break;
        case VertexAttribute.TexCoord0:
        case VertexAttribute.TexCoord1:
        case VertexAttribute.TexCoord2:
        case VertexAttribute.TexCoord3:
        case VertexAttribute.TexCoord4:
        case VertexAttribute.TexCoord5:
        case VertexAttribute.TexCoord6:
        case VertexAttribute.TexCoord7:
          flag = typeof (T) == typeof (Vector2);
          break;
        case VertexAttribute.BlendWeight:
          flag = typeof (T) == typeof (BoneWeight);
          break;
        default:
          throw new InvalidOperationException(string.Format("The requested channel '{0}' is unknown.", (object) channel));
      }
      if (!flag)
        throw new InvalidOperationException(string.Format("The requested channel '{0}' does not match the return type {1}.", (object) channel, (object) typeof (T).Name));
    }

    public static unsafe NativeSlice<T> GetVertexAttribute<T>(
      this Sprite sprite,
      VertexAttribute channel)
      where T : struct
    {
      SpriteDataAccessExtensions.CheckAttributeTypeMatchesAndThrow<T>(channel);
      SpriteChannelInfo channelInfo = SpriteDataAccessExtensions.GetChannelInfo(sprite, channel);
      NativeSlice<T> nativeSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice<T>((void*) ((IntPtr) channelInfo.buffer + channelInfo.offset), channelInfo.stride, channelInfo.count);
      NativeSliceUnsafeUtility.SetAtomicSafetyHandle<T>(ref nativeSlice, sprite.GetSafetyHandle());
      return nativeSlice;
    }

    public static unsafe void SetVertexAttribute<T>(
      this Sprite sprite,
      VertexAttribute channel,
      NativeArray<T> src)
      where T : struct
    {
      SpriteDataAccessExtensions.CheckAttributeTypeMatchesAndThrow<T>(channel);
      SpriteDataAccessExtensions.SetChannelData(sprite, channel, src.GetUnsafeReadOnlyPtr<T>());
    }

    /// <summary>
    ///   <para>Returns an array of BindPoses.</para>
    /// </summary>
    /// <param name="sprite">The sprite to retrieve the bind pose from.</param>
    /// <returns>
    ///   <para>A list of bind poses for this sprite. There is no need to dispose the returned NativeArray.</para>
    /// </returns>
    public static unsafe NativeArray<Matrix4x4> GetBindPoses(this Sprite sprite)
    {
      SpriteChannelInfo bindPoseInfo = SpriteDataAccessExtensions.GetBindPoseInfo(sprite);
      NativeArray<Matrix4x4> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<Matrix4x4>(bindPoseInfo.buffer, bindPoseInfo.count, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<Matrix4x4>(ref nativeArray, sprite.GetSafetyHandle());
      return nativeArray;
    }

    public static unsafe void SetBindPoses(this Sprite sprite, NativeArray<Matrix4x4> src)
    {
      SpriteDataAccessExtensions.SetBindPoseData(sprite, src.GetUnsafeReadOnlyPtr<Matrix4x4>(), src.Length);
    }

    /// <summary>
    ///   <para>Returns a list of indices. This is the same as Sprite.triangle.</para>
    /// </summary>
    /// <param name="sprite"></param>
    /// <returns>
    ///   <para>A read-only list of indices indicating how the triangles are formed between the vertices. The array is marked as undisposable.</para>
    /// </returns>
    public static unsafe NativeArray<ushort> GetIndices(this Sprite sprite)
    {
      SpriteChannelInfo indicesInfo = SpriteDataAccessExtensions.GetIndicesInfo(sprite);
      NativeArray<ushort> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<ushort>(indicesInfo.buffer, indicesInfo.count, Allocator.Invalid);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<ushort>(ref nativeArray, sprite.GetSafetyHandle());
      return nativeArray;
    }

    public static unsafe void SetIndices(this Sprite sprite, NativeArray<ushort> src)
    {
      SpriteDataAccessExtensions.SetIndicesData(sprite, src.GetUnsafeReadOnlyPtr<ushort>(), src.Length);
    }

    /// <summary>
    ///   <para>Returns a list of SpriteBone in this Sprite.</para>
    /// </summary>
    /// <param name="sprite">The sprite to get the list of SpriteBone from.</param>
    /// <returns>
    ///   <para>An array of SpriteBone that belongs to this Sprite.</para>
    /// </returns>
    public static SpriteBone[] GetBones(this Sprite sprite)
    {
      return SpriteDataAccessExtensions.GetBoneInfo(sprite);
    }

    /// <summary>
    ///   <para>Sets the SpriteBones for this Sprite.</para>
    /// </summary>
    /// <param name="sprite"></param>
    /// <param name="src"></param>
    public static void SetBones(this Sprite sprite, SpriteBone[] src)
    {
      SpriteDataAccessExtensions.SetBoneData(sprite, src);
    }

    /// <summary>
    ///   <para>Checks if a specific channel exists for this Sprite.</para>
    /// </summary>
    /// <param name="sprite"></param>
    /// <param name="channel"></param>
    /// <returns>
    ///   <para>True if the channel exists.</para>
    /// </returns>
    [NativeName("HasChannel")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern bool HasVertexAttribute([NotNull("ArgumentNullException")] this Sprite sprite, VertexAttribute channel);

    /// <summary>
    ///   <para>Sets the vertex count. This resizes the internal buffer. It also preserves any configurations of VertexAttributes.</para>
    /// </summary>
    /// <param name="sprite"></param>
    /// <param name="count"></param>
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern void SetVertexCount([NotNull("ArgumentNullException")] this Sprite sprite, int count);

    /// <summary>
    ///   <para>Returns the number of vertices in this Sprite.</para>
    /// </summary>
    /// <param name="sprite"></param>
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern int GetVertexCount([NotNull("ArgumentNullException")] this Sprite sprite);

    private static SpriteChannelInfo GetBindPoseInfo([NotNull("ArgumentNullException")] Sprite sprite)
    {
      SpriteChannelInfo ret;
      SpriteDataAccessExtensions.GetBindPoseInfo_Injected(sprite, out ret);
      return ret;
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern unsafe void SetBindPoseData([NotNull("ArgumentNullException")] Sprite sprite, void* src, int count);

    private static SpriteChannelInfo GetIndicesInfo([NotNull("ArgumentNullException")] Sprite sprite)
    {
      SpriteChannelInfo ret;
      SpriteDataAccessExtensions.GetIndicesInfo_Injected(sprite, out ret);
      return ret;
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern unsafe void SetIndicesData([NotNull("ArgumentNullException")] Sprite sprite, void* src, int count);

    private static SpriteChannelInfo GetChannelInfo([NotNull("ArgumentNullException")] Sprite sprite, VertexAttribute channel)
    {
      SpriteChannelInfo ret;
      SpriteDataAccessExtensions.GetChannelInfo_Injected(sprite, channel, out ret);
      return ret;
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern unsafe void SetChannelData(
      [NotNull("ArgumentNullException")] Sprite sprite,
      VertexAttribute channel,
      void* src);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern SpriteBone[] GetBoneInfo([NotNull("ArgumentNullException")] Sprite sprite);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void SetBoneData([NotNull("ArgumentNullException")] Sprite sprite, SpriteBone[] src);

    [MethodImpl(MethodImplOptions.InternalCall)]
    internal static extern int GetPrimaryVertexStreamSize(Sprite sprite);

    internal static AtomicSafetyHandle GetSafetyHandle([NotNull("ArgumentNullException")] this Sprite sprite)
    {
      AtomicSafetyHandle ret;
      SpriteDataAccessExtensions.GetSafetyHandle_Injected(sprite, out ret);
      return ret;
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void GetBindPoseInfo_Injected(Sprite sprite, out SpriteChannelInfo ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void GetIndicesInfo_Injected(Sprite sprite, out SpriteChannelInfo ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void GetChannelInfo_Injected(
      Sprite sprite,
      VertexAttribute channel,
      out SpriteChannelInfo ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void GetSafetyHandle_Injected(Sprite sprite, out AtomicSafetyHandle ret);
  }
}
